package com.talent.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.talent.common.PageResult;
import com.talent.handler.BaseException;
import com.talent.mapper.CategoryMapper;
import com.talent.mapper.ImportRecordMapper;
import com.talent.mapper.SpotMapper;
import com.talent.pojo.dto.SpotDTO;
import com.talent.pojo.entity.Category;
import com.talent.pojo.entity.ImportRecord;
import com.talent.pojo.entity.Spot;
import com.talent.service.OperationLogService;
import com.talent.service.SpotService;
import com.talent.utils.ExcelUtil;
import com.talent.utils.OperationLogUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 点位服务实现类
 */
@Service
public class SpotServiceImpl implements SpotService {

    @Autowired
    private SpotMapper spotMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private ImportRecordMapper importRecordMapper;

    private Boolean isInterrupted = false;
    /**
     * 分页查询点位
     */
    @Override
    public PageResult<Spot> pageQuery(Integer page, Integer pageSize, String name, String address, String contactPerson, String contact, String trainingInstitution, Long categoryId) {
        PageHelper.startPage(page, pageSize);
        Page<Spot> p = (Page<Spot>) spotMapper.pageQuery(name, address, contactPerson, contact, trainingInstitution, categoryId);
        return new PageResult<>(p.getResult(), p.getTotal(), page, pageSize);
    }

    /**
     * 根据ID查询点位
     */
    @Override
    public Spot getById(Long id) {
        return spotMapper.getById(id);
    }

    /**
     * 新增点位
     */
    @Override
    public void save(SpotDTO spotDTO) {
        Spot spot = new Spot();
        BeanUtils.copyProperties(spotDTO, spot);
        spotMapper.insert(spot);

        // 记录详细操作日志
        operationLogService.saveDetail(OperationLogUtils.buildCreateLog(
                "spot", spot.getId(), spot.getName(), spot));
    }

    /**
     * 更新点位
     */
    @Override
    public void update(Long id, SpotDTO spotDTO) {
        Spot spot = spotMapper.getById(id);
        if (spot == null) {
            throw new BaseException("点位不存在");
        }

        // 保存更新前的数据
        Spot oldSpot = new Spot();
        BeanUtils.copyProperties(spot, oldSpot);

        BeanUtils.copyProperties(spotDTO, spot);
        spot.setId(id);
        spotMapper.update(spot);

        // 记录详细操作日志
        operationLogService.saveDetail(OperationLogUtils.buildUpdateLog(
                "spot", id, spot.getName(), oldSpot, spot));
    }

    /**
     * 批量删除点位
     */
    @Override
    public void deleteByIds(Long[] ids) {
        if (ids == null || ids.length == 0) {
            throw new BaseException("请选择要删除的点位");
        }

        List<String> deletedSpotNames = new ArrayList<>();
        List<Long> validIds = new ArrayList<>();

        // 先验证所有点位是否存在，并收集名称用于日志
        for (Long id : ids) {
            Spot spot = spotMapper.getById(id);
            if (spot != null) {
                deletedSpotNames.add(spot.getName());
                validIds.add(id);
            }
        }

        if (validIds.isEmpty()) {
            throw new BaseException("没有找到有效的点位");
        }

        // 执行批量删除
        spotMapper.deleteByIds(validIds.toArray(new Long[0]));

        // 记录批量删除日志
        String deletedNames = String.join("、", deletedSpotNames);
        operationLogService.saveDetail(OperationLogUtils.buildCustomLog(
                "DELETE", 
                String.format("批量删除点位：成功删除 %d 个点位，包括：%s", validIds.size(), deletedNames), 
                "spot", 
                null, 
                String.format("删除了 %d 个点位", validIds.size())));
    }

    /**
     * 导入点位
     */
    @Override
    public void importSpots(MultipartFile file) {
        try {
            isInterrupted = false;
            List<List<String>> data = ExcelUtil.readExcel(file.getInputStream());
            if (data.isEmpty()) {
                throw new BaseException("Excel文件为空");
            }
            importRecordMapper.deleteAll();
            // 获取所有分类，建立映射关系
            List<Category> categories = categoryMapper.getByType(null);
            Map<String, Long> categoryMap = categories.stream()
                    .collect(Collectors.toMap(Category::getName, Category::getId));
            int successCount = 0;
            // 跳过标题行
            List<String> importedSpots = new ArrayList<>();
            for (int i = 1; i < data.size(); i++) {
                Spot spot = new Spot();
                ImportRecord importRecord = new ImportRecord();
                importRecord.setSuccess();
                importRecord.setRowIndex(i+1);
                List<String> row = data.get(i);
                // 点位名称
                String spotName = row.get(0) != null ? row.get(0).trim() : "";
                spot.setName(spotName);
                importRecord.setSpotName(spotName);
                // 点位分类名称
                String categoryName = row.get(1) != null ? row.get(1).trim() : "";
                importRecord.setCategoryName(categoryName);
                if (!StringUtils.hasText(spotName)) {
                    importRecord.setFailed("点位名称不能为空");
                }
                if (!StringUtils.hasText(categoryName)) {
                    importRecord.setFailed("点位分类不能为空");
                }
                Long categoryId = categoryMap.get(categoryName);
                if (categoryId == null) {
                    importRecord.setFailed("点位分类不存在");
                }
                spot.setCategoryId(categoryId);
                spot.setContent(row.size() > 2 ? row.get(2) : null); // 基本内容
                spot.setAddress(row.size() > 3 ? row.get(3) : null); // 地址
                spot.setContact(row.size() > 4 ? row.get(4) : null); // 联系方式
                spot.setContactPerson(row.size() > 5 ? row.get(5) : null); // 联系人
                spot.setTrainingInstitution(row.size() > 6 ? row.get(6) : null); // 培训机构
                spot.setTrainingType(row.size() > 7 ? row.get(7) : null); // 培训工种
                spot.setLink(row.size() > 8 ? row.get(8) : null); // 跳转链接
                spot.setTalentManager(row.size() > 9 ? row.get(9) : null); // 人才管家
                // 经纬度
                if (row.size() > 10 && StringUtils.hasText(row.get(10))) {
                    String lngStr = row.get(10).replaceAll("[^\\d.\\-]", "");
                    try{
                    spot.setLng(new BigDecimal(lngStr));
                    }catch(NumberFormatException e){
                        importRecord.setFailed("经度格式错误");
                    }
                }
                if (row.size() > 11 && StringUtils.hasText(row.get(11))) {
                    String latStr = row.get(11).replaceAll("[^\\d.\\-]", "");
                    try{
                        spot.setLng(new BigDecimal(latStr));
                    }catch(NumberFormatException e){
                        importRecord.setFailed("经度格式错误");
                    }
                }
                importRecordMapper.insert(importRecord);

                if("SUCCESS".equals(importRecord.getStatus())) {
                    successCount++;
                    spotMapper.insert(spot);
                    importedSpots.add(spot.getName());
                }
                if(isInterrupted) {
                    break;
                }
                //如果用户没有充值1000w以上，线程停止1秒钟，让用户体验更好
                //Thread.sleep(1000);
            }
            ImportRecord importRecord = new ImportRecord();
            importRecord.setComplete();
            importRecord.setRowIndex(0);
            importRecordMapper.insert(importRecord);
            // 记录批量导入日志
            operationLogService.saveDetail(OperationLogUtils.buildCustomLog(
                    "IMPORT",
                    String.format("批量导入点位：成功导入 %d 个点位，包括：%s",
                            successCount, String.join("、", importedSpots)),
                    "spot",
                    null,
                    file.getOriginalFilename()));
        } catch (IOException e) {
            throw new BaseException("文件读取失败");
        }
    }

    /**
     * 导出点位
     */
    @Override
    public void exportSpots(Long[] ids, HttpServletResponse response) {
        List<Spot> spots = spotMapper.list(ids);
        
        List<String> headers = Arrays.asList(
            "点位名称", "点位分类", "基本内容", "地址", "联系方式", "联系人", "培训机构", "培训工种", "跳转链接", "人才管家", "经度", "纬度", "创建时间"
        );
        
        List<List<String>> data = new ArrayList<>();
        List<String> exportedSpotNames = new ArrayList<>();
        for (Spot spot : spots) {
            List<String> row = Arrays.asList(
                spot.getName(),
                spot.getCategory(),
                spot.getContent(),
                spot.getAddress(),
                spot.getContact(),
                spot.getContactPerson() != null ? spot.getContactPerson() : "",
                spot.getTrainingInstitution() != null ? spot.getTrainingInstitution() : "",
                spot.getTrainingType() != null ? spot.getTrainingType() : "",
                spot.getLink() != null ? spot.getLink() : "",
                spot.getTalentManager() != null ? spot.getTalentManager() : "",
                spot.getLng() != null ? spot.getLng().toString() : "",
                spot.getLat() != null ? spot.getLat().toString() : "",
                spot.getCreateTime() != null ? spot.getCreateTime().toString() : ""
            );
            data.add(row);
            exportedSpotNames.add(spot.getName());
        }
        
        try {
            ExcelUtil.writeExcel(headers, data, "spots.xlsx", response);
            
            // 记录导出日志
            String exportDetail = ids != null && ids.length > 0 
                    ? String.format("导出指定点位：共 %d 个，包括：%s", spots.size(), String.join("、", exportedSpotNames))
                    : String.format("导出全部点位：共 %d 个", spots.size());
            
            operationLogService.saveDetail(OperationLogUtils.buildCustomLog(
                    "EXPORT", 
                    exportDetail, 
                    "spot", 
                    null, 
                    "spots.xlsx"));
                    
        } catch (IOException e) {
            throw new BaseException("文件导出失败");
        }
    }

    @Override
    public List<Spot> getSpots() {
        return spotMapper.getAll();
    }

    @Override
    public void stopImport() {
        isInterrupted = true;
    }
    /**
     * 为点位分配服务菜单
     */
    @Override
    public void assignServices(Long spotId, List<Long> serviceIds) {
        // 验证点位是否存在
        Spot spot = spotMapper.getById(spotId);
        if (spot == null) {
            throw new BaseException("点位不存在");
        }

        // 保存更新前的服务ID
        String oldServiceIds = spot.getServiceIds();

        // 将服务ID列表转换为逗号分隔的字符串
        String serviceIdsStr = null;
        if (serviceIds != null && !serviceIds.isEmpty()) {
            serviceIdsStr = serviceIds.stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
        }

        // 更新点位的服务ID字段
        spotMapper.updateSpotServices(spotId, serviceIdsStr);

        // 记录详细操作日志
        String actionDetail = String.format("为点位 %s 分配服务菜单：%s", 
                spot.getName(), 
                serviceIds != null && !serviceIds.isEmpty() 
                        ? serviceIds.stream().map(String::valueOf).collect(Collectors.joining("、"))
                        : "清空所有服务");
        
        operationLogService.saveDetail(OperationLogUtils.buildCustomLog(
                "ASSIGN_SERVICES", 
                actionDetail, 
                "spot", 
                spotId, 
                spot.getName()));
    }
}
